package login.logic;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import lion.lan.ILanIoExecutor;
import lion.lan.Netty4LanClient;
import lion.lan.LanClientSession;
import lion.netty4.message.RequestMessage;
import login.LoginServer;
import login.concurrent.GsSyncRequest;
import login.lan.GarenaLogin2GsMessage;
import login.lan.Login2GsMessage;
import login.lan.QqLogin2GsMessage;
import login.lan.SifubaLogin2GsMessage;
import login.lan.SifubaPayment2GsMessage;
import login.lan.SifubaQueryRole2GsMessage;

public class LoginLanClientManager implements ILanIoExecutor {

	private Netty4LanClient lanClient;

	private Map<String, LanClientSession> gsConnectionSessionMap = new HashMap<String, LanClientSession>();

	private static Logger logger = LoggerFactory.getLogger(LoginLanClientManager.class);

	public LoginLanClientManager() {
		lanClient = new Netty4LanClient(this, LoginServer.executorService);
		// gsConnectSession = new LanClientSession(lanClient);
	}

	public void shutdown() {
		if (lanClient != null) {
			lanClient.close();
		}
	}

	public boolean connect(String hostName, int port) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(hostName + ":" + port);
		if (gsConnectionSession == null) {
			gsConnectionSession = new LanClientSession(lanClient);
			gsConnectionSessionMap.put(hostName + ":" + port, gsConnectionSession);
		}
		// already connected
		if (gsConnectionSession.isConnected()) {
			return true;
		}
		boolean ret = false;
		synchronized (gsConnectionSession) {
			try {
				gsConnectionSession.connect(hostName, port);
				ret = true;
			} catch (Exception e) {
				logger.error("lan connect to " + hostName + ":" + port + " error!", e);
			}
		}
		return ret;
	}

	public ChannelFuture sendMessage(String hostName, int port, long sessionId, int uid, int serverId) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(hostName + ":" + port);
		Login2GsMessage gsMessage = new Login2GsMessage(gsConnectionSession.alloc());
		gsMessage.setMessage(sessionId, uid,serverId);
		logger.info("send Login2GsMessage,host={},sid={},uid={}", hostName, sessionId, uid);
		return gsConnectionSession.writeAndFlush(gsMessage);
	}

	public ChannelFuture sendGarena2Gs(String hostName, int port, long sessionId, String openId, String accessToken,int serverId) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(hostName + ":" + port);
		GarenaLogin2GsMessage gsMessage = new GarenaLogin2GsMessage(gsConnectionSession.alloc());
		gsMessage.setMessage(sessionId, openId, accessToken,serverId);
		logger.info("send GarenaLogin2GsMessage,host={},sid={},openId={},accessToken={},serverId={}", hostName,
				sessionId, openId, accessToken, serverId);
		return gsConnectionSession.writeAndFlush(gsMessage);
	}

	@Override
	public void execute(Channel channel, RequestMessage msg) throws IOException {
		logger.info("reveive msgCode={}", msg.getMsgCode());
		switch (msg.getMsgCode()) {
		case 11004:
			GsSyncRequest.getInstance().doReceive(msg);
			break;
		default:
			break;
		}
	}

	public ChannelFuture sendZyPayment(String gsHostName, int port, String userid, String orderid, int money, int time,
			int other, int serverid) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(gsHostName + ":" + port);
		SifubaPayment2GsMessage gsMessage = new SifubaPayment2GsMessage(gsConnectionSession.alloc());
		gsMessage.setMessage(userid, orderid, money, time, other,serverid);
		logger.info(
				"send ZyPayment2GsMessage,host={},userid={},orderid={},money={},time={},other={},serverid={}",
				gsHostName, userid, orderid, money, time, other,serverid);
		return gsConnectionSession.writeAndFlush(gsMessage);
	}

	public ChannelFuture queryRole2Gs(String gsHostName, int port, String userid) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(gsHostName + ":" + port);
		SifubaQueryRole2GsMessage gsMessage = new SifubaQueryRole2GsMessage(gsConnectionSession.alloc());
		gsMessage.setMessage(userid);
		logger.info("sifuba query role,host={},userid={}", gsHostName, userid);
		GsSyncRequest.getInstance().setRetMsg(null);
		return gsConnectionSession.writeAndFlush(gsMessage);
	}

	public ChannelFuture sendSifuba2Gs(String gsHostName, int port, long sessionId, String userId, int serverId) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(gsHostName + ":" + port);
		SifubaLogin2GsMessage gsMessage = new SifubaLogin2GsMessage(gsConnectionSession.alloc());
		gsMessage.setMessage(sessionId, userId, serverId);
		logger.info("send SifubaLogin2GsMessage,host={},sid={},userId={}", gsHostName, sessionId, userId);
		return gsConnectionSession.writeAndFlush(gsMessage);
	}

	public ChannelFuture sendQq2Gs(String gsHostName, int lanPort, long sessionId, String openId, String access_token) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(gsHostName + ":" + lanPort);
		QqLogin2GsMessage gsMessage = new QqLogin2GsMessage(gsConnectionSession.alloc());
		gsMessage.setMessage(sessionId, openId,access_token);
		logger.info("send QqLogin2GsMessage,host={},sid={},openId={},access_token={}", gsHostName, sessionId, openId,access_token);
		return gsConnectionSession.writeAndFlush(gsMessage);
	}

}
